using UnityEngine;
using System.Collections.Generic;
using System.Collections;

public class AudioManager : MonoBehaviour
{
    // 单例实例
    // 使用属性封装，提供只读访问权限
    public static AudioManager Instance { get; private set; }

    // 音效列表
    // AudioClip是Unity中存储音频数据的资源文件
    // 在Inspector面板中可以拖拽添加多个音效文件
    public List<AudioClip> soundEffects = new List<AudioClip>();

    // 背景音乐AudioSource组件
    // AudioSource是实际播放音频的组件，负责音频播放控制
    public AudioSource musicSource;

    // 音效AudioSource预制体
    // 用于创建音效播放器的模板对象
    public GameObject soundEffectPrefab;

    // 音效对象池
    // 用于管理可重用的AudioSource组件，避免频繁创建销毁
    private List<AudioSource> soundEffectPool = new List<AudioSource>();
    // 对象池初始大小
    private int poolSize = 5;

    // Awake在对象初始化时调用
    void Awake()
    {
        // 单例模式实现
        if (Instance == null)  // 检查是否已存在实例
        {
            Instance = this;  // 设置当前实例为单例实例
            DontDestroyOnLoad(gameObject); // 使对象在场景加载时不被销毁

            // 初始化对象池
            InitializePool();
        }
        else
        {
            // 如果已存在实例则销毁新实例，确保只有一个AudioManager存在
            Destroy(gameObject);
        }
    }

    // 初始化音效对象池
    void InitializePool()
    {
        for (int i = 0; i < poolSize; i++)
        {
            // 实例化预制体
            GameObject go = Instantiate(soundEffectPrefab, transform);
            // 获取AudioSource组件
            AudioSource source = go.GetComponent<AudioSource>();
            // 添加到对象池
            soundEffectPool.Add(source);
            // 初始设置为非激活状态
            go.SetActive(false);
        }
    }

    // 播放背景音乐
    // 参数：
    // musicClip - 要播放的音乐剪辑
    // loop - 是否循环播放（默认true）
    // volume - 播放音量（0.0-1.0，默认1.0）
    public void PlayMusic(AudioClip musicClip, bool loop = true, float volume = 1f)
    {
        musicSource.clip = musicClip;  // 设置音频剪辑
        musicSource.loop = loop;      // 设置循环
        musicSource.volume = volume;  // 设置音量
        musicSource.Play();           // 开始播放
    }

    // 通过索引播放音效
    // 参数：
    // soundIndex - soundEffects列表中的索引
    // volume - 播放音量（0.0-1.0，默认1.0）
    public void PlaySound(int soundIndex, float volume = 1f)
    {
        // 检查索引是否有效
        if (soundIndex >= 0 && soundIndex < soundEffects.Count)
        {
            // 调用通用音效播放方法
            PlaySound(soundEffects[soundIndex], volume);
        }
        else
        {
            Debug.LogWarning("Sound index out of range!");
        }
    }

    // 通过AudioClip播放音效（核心方法）
    // 参数：
    // clip - 要播放的音效剪辑
    // volume - 播放音量（0.0-1.0，默认1.0）
    public void PlaySound(AudioClip clip, float volume = 1f)
    {
        // 从对象池获取可用的AudioSource
        AudioSource availableSource = GetAvailableSource();
        if (availableSource != null)
        {
            availableSource.clip = clip;       // 设置音频剪辑
            availableSource.volume = volume;  // 设置音量
            availableSource.Play();            // 开始播放
            // 启动协程，播放完成后回收AudioSource
            StartCoroutine(ReturnToPool(availableSource));
        }
    }

    // 从对象池获取可用的AudioSource
    private AudioSource GetAvailableSource()
    {
        // 遍历对象池寻找未在播放的AudioSource
        foreach (AudioSource source in soundEffectPool)
        {
            if (!source.isPlaying)  // 检查是否正在播放
            {
                source.gameObject.SetActive(true);  // 激活对象
                return source;  // 返回可用源
            }
        }

        // 如果没有可用源，动态创建一个新的AudioSource
        GameObject newGo = Instantiate(soundEffectPrefab, transform);
        AudioSource newSource = newGo.GetComponent<AudioSource>();
        soundEffectPool.Add(newSource);  // 加入对象池
        return newSource;  // 返回新创建的源
    }

    // 音效播放完毕后返回对象池的协程
    private IEnumerator ReturnToPool(AudioSource source)
    {
        // 等待音频播放结束
        yield return new WaitWhile(() => source.isPlaying);
        // 播放完成后停用对象
        source.gameObject.SetActive(false);
    }

    // 设置背景音乐音量
    // 参数：
    // volume - 目标音量（0.0-1.0）
    public void SetMusicVolume(float volume)
    {
        musicSource.volume = volume;
    }

    // 停止所有音效
    public void StopAllSounds()
    {
        // 遍历对象池停止所有音效
        foreach (AudioSource source in soundEffectPool)
        {
            source.Stop();  // 停止播放
            source.gameObject.SetActive(false);  // 停用对象
        }
    }

    // 停止背景音乐
    public void StopMusic()
    {
        musicSource.Stop();  // 停止音乐播放
    }
}